using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;

using Pegasus.Diagnostics;

namespace Pegasus.Collections.Generic
{
	/// <summary>
	/// This diectionary know how to persist itself and save value in the windows current user data directory.
	/// </summary>
	/// <typeparam name="TKey"></typeparam>
	/// <typeparam name="TValue"></typeparam>
	[Serializable]
	public class DictionaryUserData<TKey, TValue> : DictionaryApplicationData<TKey, TValue>
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		public DictionaryUserData( string storeName ) 
			: base( storeName )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		/// <param name="dictionary">The dictionary.</param>
		public DictionaryUserData( string storeName, IDictionary<TKey, TValue> dictionary )
			: base( storeName, dictionary )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
			ParamCode.AssertNotNull( dictionary, "dictionary" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		/// <param name="comparer">The comparer.</param>
		public DictionaryUserData( string storeName, IEqualityComparer<TKey> comparer )
			: base( storeName, comparer )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
			ParamCode.AssertNotNull( comparer, "comparer" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		/// <param name="capacity">The capacity.</param>
		public DictionaryUserData( string storeName, int capacity )
			: base( storeName, capacity )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
			ParamCode.AssertRange( capacity, 0, int.MaxValue, "capacity" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		/// <param name="dictionary">The dictionary.</param>
		/// <param name="comparer">The comparer.</param>
		public DictionaryUserData( string storeName, IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer )
			: base( storeName, dictionary, comparer )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
			ParamCode.AssertNotNull( dictionary, "dictionary" );
			ParamCode.AssertNotNull( comparer, "comparer" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="storeName">Name of the store.</param>
		/// <param name="capacity">The capacity.</param>
		/// <param name="comparer">The comparer.</param>
		public DictionaryUserData( string storeName, int capacity, IEqualityComparer<TKey> comparer )
			: base( storeName, capacity, comparer )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( storeName, "storeName" );
			ParamCode.AssertRange( capacity, 0, int.MaxValue, "capacity" );
			ParamCode.AssertNotNull( comparer, "comparer" );
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DictionaryUserData&lt;TKey, TValue&gt;"/> class.
		/// </summary>
		/// <param name="info">A <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> object containing the information required to serialize the <see cref="T:System.Collections.Generic.Dictionary`2"></see>.</param>
		/// <param name="context">A <see cref="T:System.Runtime.Serialization.StreamingContext"></see> structure containing the source and destination of the serialized stream associated with the <see cref="T:System.Collections.Generic.Dictionary`2"></see>.</param>
		protected DictionaryUserData( SerializationInfo info, StreamingContext context )
			: base( info, context )
		{
			// Check Parameters
			ParamCode.AssertNotNull( info, "info" );
			ParamCode.AssertNotNull( context, "context" );
		}

		/// <summary>
		/// Gets the store filename.
		/// </summary>
		/// <returns></returns>
		protected override string GetStoreFilename()
		{
			string folder = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData );
			string filename = StoreName + ".xml";

			return Path.Combine( folder, filename );
		}
	}
}
